//package com.heima.seata.config;
//
//import com.alibaba.druid.pool.DruidDataSource;
//import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
//import com.baomidou.mybatisplus.core.MybatisConfiguration;
//import com.baomidou.mybatisplus.core.parser.ISqlParser;
//import com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser;
//import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
//import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
//import io.seata.rm.datasource.DataSourceProxy;
//import org.apache.ibatis.plugin.Interceptor;
//import org.apache.ibatis.session.SqlSessionFactory;
//import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
//import org.springframework.boot.context.properties.ConfigurationProperties;
//import org.springframework.boot.context.properties.EnableConfigurationProperties;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Lazy;
//import org.springframework.context.annotation.Primary;
//import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
//
//import javax.sql.DataSource;
//import java.util.ArrayList;
//import java.util.List;
////作用：：配置数据源代理
//@Configuration
////启用 MybatisPlusProperties 的配置属性绑定，
//// 通常用于将 application.properties 或 application.yml 中的配置属性注入到对应的 Bean 中。
//@EnableConfigurationProperties({MybatisPlusProperties.class})
//public class DataSourcesProxyConfig {//用于配置数据源、SQL 会话工厂和其他与 MyBatis 相关的 Bean
//
//    @Bean
//    //将以 spring.datasource 为前缀的配置属性注入到 DruidDataSource 的实例中。
//    @ConfigurationProperties(prefix = "spring.datasource")
//    public DataSource druidDataSource() {
//        return new DruidDataSource();
//    }
//    //创建代理数据源
//
//    //标识这个 Bean 是优先注入的，如果有多个同类型的 Bean，Spring 会优先使用这个类。
//    //@Primary标识必须配置在代码数据源上，否则本地事务失效
//    @Primary
//    @Bean
//    public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {
//        //创建一个 DataSourceProxy，代理对实际数据源（Druid 数据源）的访问。
//        return new DataSourceProxy(druidDataSource);
//    }//DataSourceProxy 依赖于 druidDataSource
//
//    private final MybatisPlusProperties properties;
//
//    public DataSourcesProxyConfig(MybatisPlusProperties properties) {
//        this.properties = properties;
//    }
//
//    //报错The bean 'sqlSessionFactory', defined in class path resource [com/heima/seata/config/DataSourcesProxyConfig.class],
//    // could not be registered. A bean with that name has already been defined in class path resource
//    // [com/baomidou/mybatisplus/autoconfigure/MybatisPlusAutoConfiguration.class] and overriding is disabled.
////在你的 Spring 应用中，存在两个名为 sqlSessionFactory 的 bean 定义，导致冲突。
//// 其中一个是在 DataSourcesProxyConfig 中定义的，
//// 而另一个是在 MyBatis-Plus 的自动配置类 MybatisPlusAutoConfiguration 中定义的。
//
//    //1.解决方法：允许 Bean 的覆盖
////    spring:
////    main:
////    allow-bean-definition-overriding: true #允许 Bean 的覆盖
//    //2.解决方法：自定义的名称
////    @Bean(name = "myCustomSqlSessionFactory")
////    public SqlSessionFactory sqlSessionFactory() {
////        // 创建并返回 SqlSessionFactory 实例
////    }
//
////如果你清楚需要注入哪一个 Bean，可以在注入时使用 @Qualifier 注解指定具体的 Bean 名称。
//// 例如：  @Autowired
////        @Qualifier("myCustomSqlSessionFactory")
////        private SqlSessionFactory sqlSessionFactory;
//
//    //替换SqlSessionFactory的DataSource
//    @Primary // 标识为主要使用的 Bean
//    @Bean//(name = "myCustomSqlSessionFactory")
//    //可以使用 @ConditionalOnMissingBean 进行条件注入，从而只在没有其他 Bean 存在时才创建某些 Bean
//    //@ConditionalOnMissingBean(name = "sqlSessionFactory")//(DataSourceProxy.class)//
//    public MybatisSqlSessionFactoryBean sqlSessionFactory(DataSourceProxy dataSourceProxy) throws Exception {
////创建的是 MybatisSqlSessionFactoryBean，它替代了 MyBatis 的 SqlSessionFactoryBean，以支持 MyBatis-Plus 的特性。
//
//        // 这里必须用 MybatisSqlSessionFactoryBean 代替了 SqlSessionFactoryBean，否则 MyBatisPlus 不会生效
//        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
//        mybatisSqlSessionFactoryBean.setDataSource(dataSourceProxy);
//        mybatisSqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
////设置代理数据源，并配置 mapper 的位置、MyBatis 的配置等信息。
//        mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
//                .getResources("classpath*:/mapper/*.xml"));
//
//        MybatisConfiguration configuration = this.properties.getConfiguration();
//        if(configuration == null){
//            configuration = new MybatisConfiguration();
//        }
//        mybatisSqlSessionFactoryBean.setConfiguration(configuration);
//
//
//        // 设置分页插件****
//        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
//        List<ISqlParser> sqlParserList = new ArrayList<ISqlParser>();
//        // 攻击 SQL 阻断解析器、加入解析链
//        //通过添加 BlockAttackSqlParser（虽然它已被弃用，可能需要替换为其他安全解析器）
//        // 来支持 SQL 注入的防护机制。
//        sqlParserList.add(new BlockAttackSqlParser());
//        paginationInterceptor.setSqlParserList(sqlParserList);
//        Interceptor[] plugins = { paginationInterceptor };
//        mybatisSqlSessionFactoryBean.setPlugins( plugins );
//
//        return mybatisSqlSessionFactoryBean;
//    }
//}